﻿using System;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using AuthorizeAttribute = System.Web.Mvc.AuthorizeAttribute;


namespace ContactMvc4TB.Helpers.RightsManagement
{

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        #region Member
        private AuthorizationContext CurrentContext { get; set; }
        #endregion

        #region Konstruktor
        /// <summary>
        /// Es muss nichts übergeben werden, da controller und action direkt hier ausgelesen werden können
        /// </summary>
        public CustomAuthorizeAttribute()
        {
        }
        #endregion

        #region Public Functions
        /// <summary>
        /// Funktion die ausgeführt wird, wenn das Attribut "genutzt" wird, das Authorisation Attribut wird immer als erstes Attribut ausgeführt.
        /// </summary>
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
            //Der Filtercontext wird benötigt um auf die RequestDaten zuzugreifen, 
            //z.b. auf die Id, Action oder den Controller auf den zugegriffen werden soll.
            CurrentContext = filterContext;
          
            //Wenn kein User eingeloggt ist, dann hat er auch keinen Zugriff.
            if (!HttpContext.Current.User.Identity.IsAuthenticated)
            {
                //Wenn der User nicht eingeloggt ist, auf die Loginseite verweisen
                filterContext.Result = new HttpUnauthorizedResult();
            }
            else
            {
                //Prüfen der passenden Rechte für die einzelnen Actions/Methoden 
                if (!CheckRights())
                {
                    //Auf die Startseite verweisen, wenn der User keinen Zugriff auf den Kontent hat, den er angefordert hat.
                    filterContext.Result = new HttpUnauthorizedResult();
                    //Oder auf eine beliebige Andere Webseite verweisen, wenn man nicht unbefingt die Startseite anzeigen möchte.
                    //filterContext.Result = new RedirectResult("~/Home/Index");
                }
            }

            //Wenn alles i.o. ist "nichts" unternehmen und einfach beim Aufbau der Seite weitermachen.
        }
        #endregion

        #region Private Functions
        protected void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            var challengeMessage = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
            throw new HttpResponseException(challengeMessage);
        }

        /// <summary>
        /// Prüfen um welchen Controller es sich handelt und die passende Sicherheitsprüfung vornehmen
        /// </summary>
        /// <returns>TRUE->Darf zugreifen | FALSE->Darf nicht zugreifen</returns>
        private bool CheckRights()
        {
            //Wir können hier recht einfach ermitteln um welchen Controller oder View es sich handelt den wir gerade 
            //überprüfen wollen - wenn wir erst einmal von der Standardroute ausgehen.
            string controllerName = CurrentContext.RouteData.GetRequiredString("controller");
            string actionName = CurrentContext.RouteData.GetRequiredString("action");
            string id = CurrentContext.RouteData.Values.ContainsKey("id") ? CurrentContext.RouteData.Values["id"].ToString() : null;

            //Den aktuell eingeloggten User ermitteln für den die Rechte geprüft werden sollen 
            //Der wert der im Username steht legen wir beim Login fest
            //bei "FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe)" 
            //wird hier der Username oder auch die UserId angezeigt.
            string userName = HttpContext.Current.User.Identity.Name;
            

            //Prüfen welcher Controller das Authorize Attribut aufgerufen hat und dann schauen welche Action aufgerufen wurde.
            switch (controllerName)
            {
                case "Home":
                    //Rechteprüfung für den jewiligen Controller und evtl. auch auf die 
                    //jeweilige Action bezogen durchführen
                    return CheckHomeRights();
                    break;

                case "Person":
                    break;

            }

            return true;
        }

        /// <summary>
        /// Prüft alle Rechte für den HomeController und den enthaltenen Actions
        /// </summary>
        /// <returns></returns>
        private  bool CheckHomeRights()
        {
            return true;
        }
        #endregion
    }
}